package com.sdp.wx.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sdp.core.bizc.db.Query;
import com.sdp.core.bizc.utils.ApplicationContextUtils;
import com.sdp.core.bizc.utils.UniqueCheckTools;
import com.sdp.core.bizc.vo.BusinessContext;
import com.sdp.core.bizc.vo.DataCenter;
import com.sdp.core.bizc.vo.Result;
import com.sdp.flow.db.entity.ActHiComment;
import com.sdp.flow.db.service.IWorkflowService;
import com.sdp.flow.dto.FlowParam;
import com.sdp.flow.utils.FlowConstants;
import com.sdp.right.entity.SysEmp;
import com.sdp.right.service.RightExtService;
import com.sdp.right.utils.RightConstants;
import com.sdp.wx.db.wx_emp.entity.WxEmp;
import com.sdp.wx.db.wx_emp.service.IWxEmpService;
import com.sdp.wx.db.wx_emp_entry.entity.WxEmpEntry;
import com.sdp.wx.db.wx_emp_entry.service.IWxEmpEntryService;
import com.sdp.wx.utils.CurrentLoginEmp;
import com.sdp.wx.utils.WxConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zsp
 * @since 2024-01-24
 */
@RestController
@RequestMapping("/WxEmpEntryController")
public class WxEmpEntryController {
    @Autowired
    private Query query;
    @Autowired
    private CurrentLoginEmp currentLoginEmp;
    @Autowired
    private UniqueCheckTools uniqueCheckTools;
    @Autowired
    private IWorkflowService workflowService;
    @Autowired
    private IWxEmpEntryService iWxEmpEntryService;
    @Autowired
    private RightExtService rightExtService;
    @Autowired
    private IWxEmpService iWxEmpService;
    @PostMapping(value = "/page")
    public Result<?> page(@RequestBody DataCenter dataCenter) {
        return Result.ok(query.page(iWxEmpEntryService, WxEmpEntry.class, dataCenter));
    }
    @PostMapping(value = "/save")
    @Transactional(rollbackFor=Exception.class)
    public Result<?> save(@RequestBody WxEmpEntry wxEmpEntry) {
        if(wxEmpEntry==null) {
            return Result.error("员工入职申请为空");
        }
        JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
        if(StringUtils.isEmpty(wxEmpEntry.getKeyId())) {
            Result<?> r = uniqueCheckTools.isUniqueSingle(iWxEmpEntryService, WxEmpEntry.class, new String[] {"empNo"}, "keyId", wxEmpEntry, null, false);
            if(r==null || !r.isSuccess()) {
                return Result.error("员工工号不能重复");
            }
             r = uniqueCheckTools.isUniqueSingle(iWxEmpEntryService, WxEmpEntry.class, new String[] {"empCardCode"}, "keyId", wxEmpEntry, null, false);
            if(r==null || !r.isSuccess()) {
                return Result.error("身份账号不能重复");
            }
            WxEmp wxEmp=new WxEmp();
            wxEmp.setAccountNo(wxEmpEntry.getEmpNo());
            wxEmp.setEmpNo(wxEmpEntry.getEmpNo());
            Result<?> rs = uniqueCheckTools.isUniqueSingle(iWxEmpService, WxEmp.class, new String[] {"empNo","accountNo"}, "keyId", wxEmp, null, false);
            if(rs==null || !rs.isSuccess()) {
                return Result.error("员工工号不能重复");
            }
            wxEmpEntry.setCreateTime(LocalDateTime.now());
            wxEmpEntry.setIsFinish(WxConstants.否.getCode());
            wxEmpEntry.setApprovalState(WxConstants.流程审批状态_未提交.getCode());
            wxEmpEntry.setApplicationEmpNo(emp.getString("empNo"));
            wxEmpEntry.setApplicationEmpName(emp.getString("empName"));
            iWxEmpEntryService.save(wxEmpEntry);
        }else {
            Result<?> r = uniqueCheckTools.isUniqueSingle(iWxEmpEntryService, WxEmpEntry.class, new String[] {"empNo"}, "keyId", null, wxEmpEntry, false);
            if(r==null || !r.isSuccess()) {
                return Result.error("员工工号不能重复");
            }
            r = uniqueCheckTools.isUniqueSingle(iWxEmpEntryService, WxEmpEntry.class, new String[] {"empCardCode"}, "keyId", null, wxEmpEntry, false);
            if(r==null || !r.isSuccess()) {
                return Result.error("身份证号不能重复");
            }
            iWxEmpEntryService.updateById(wxEmpEntry);

        }

        return Result.ok();
    }

    @PostMapping(value = "/saveAndStartFlow")
    @Transactional(rollbackFor=Exception.class)
    public Result<?> saveAndStartFlow(@RequestBody WxEmpEntry wxEmpEntry) {
        if(wxEmpEntry==null) {
            return Result.error("员工入职申请为空");
        }
        Result<?> r = ApplicationContextUtils.getBean(WxEmpEntryController.class).save(wxEmpEntry);
        if(r==null || !r.isSuccess()) {
            return r;
        }
        JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
        // 如果是分厂招聘流程--军品分厂--民品分厂 否则走机关招聘
        if(wxEmpEntry.getOrgNo().equals(WxConstants.民品分厂.getCode())|| wxEmpEntry.getOrgNo().equals(WxConstants.军品分厂.getCode())){
            wxEmpEntry.setTemplateId(WxConstants.分厂招聘流程模版.getCode());
        }else{
            wxEmpEntry.setTemplateId(WxConstants.机关招聘流程_模版.getCode());
        }
        //设置审批状态
        wxEmpEntry.setApprovalState(WxConstants.流程审批状态_审批中.getCode());

        //发起流程
        FlowParam flowParam = new FlowParam();
        flowParam.setUserId(emp.getString("empNo"));
        flowParam.setTemplateId(wxEmpEntry.getTemplateId());
        flowParam.setBizId(wxEmpEntry.getKeyId());

        //指定审批人
        Map<String, Object> variableMap = new HashMap<>();
        BusinessContext businessContext = new BusinessContext();
        businessContext.put(WxEmpEntry.class, wxEmpEntry);
        variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, wxEmpEntry.getApprover());
        variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxEmpEntryController");
        variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
        variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);
        flowParam.setVariableMap(variableMap);


        String instanceId = workflowService.startFlowAndCommit(flowParam);
        if (StringUtils.isEmpty(instanceId)) {
            return Result.error("流程启动失败!");
        }

        //发起成功设置流程实例Id
        wxEmpEntry.setInstanceId(instanceId);
        iWxEmpEntryService.updateById(wxEmpEntry);
        return Result.ok(wxEmpEntry);
    }
    /**
     * 流程提交
     * @param wxEmpEntry
     * @return
     */
    @PostMapping(value = "/commit")
    @Transactional(rollbackFor=Exception.class)
    public Result<?> commit(@RequestBody WxEmpEntry wxEmpEntry) {
        if(wxEmpEntry == null) {
            return Result.error("入职申请信息为空");
        }
        if (StringUtils.isEmpty(wxEmpEntry.getKeyId())) {
            return Result.error("入职申请信息内码为空");
        }

        JSONObject emp = currentLoginEmp.getCurrentEmpInfo();
        //提交流程
        if (StringUtils.isEmpty(wxEmpEntry.getTaskId())) {
            return Result.error("入职申请审批信息不完整");
        }
        FlowParam flowParam = new FlowParam();
        flowParam.setUserId(emp.getString("empNo"));

        flowParam.setTaskId(wxEmpEntry.getTaskId());
        if (!StringUtils.isEmpty(wxEmpEntry.getIsPass())) {
            Map<String, Object> variableMap = new HashMap<>();
            variableMap.put("isPass", wxEmpEntry.getIsPass());
            variableMap.put("link", wxEmpEntry.getLink());
            variableMap.put("userName", emp.getString("empName"));
            variableMap.put("userAvatar", emp.getString("profilePicture"));
            variableMap.put("userSign", emp.getString("nameSign"));
            BusinessContext businessContext = new BusinessContext();
            businessContext.put(WxEmpEntry.class, wxEmpEntry);

            String currentNode = workflowService.getCurrentNode(wxEmpEntry.getTaskId());
            if((WxConstants.是.getCode().equals(wxEmpEntry.getIsPass()) && ( WxConstants.分厂招聘流程_厂领导审批名称.getCode().equals(currentNode))||WxConstants.机关招聘流程_最后厂领导审批名称.getCode().equals(currentNode))||(FlowConstants.flow_end_value.equals(wxEmpEntry.getLink()))) {
                //如果节信息是结束
                //或者最后一个环节，没有环节信息，并且是同意通过
                variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxEmpEntryController");
                variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowEndListener");
            }else {
                variableMap.put(WxConstants.流程监听器中执行的类.getCode(), "com.sdp.wx.controller.WxEmpEntryController");
                variableMap.put(WxConstants.流程监听器中执行类的方法.getCode(), "flowCommitListener");
            }
            variableMap.put(WxConstants.流程监听器中执行类的方法的参数.getCode(), businessContext);


            if (WxConstants.否.getCode().equals(wxEmpEntry.getIsPass())) {
                variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, wxEmpEntry.getApplicationEmpNo());
                if(StringUtils.isEmpty(wxEmpEntry.getApprovalOpinion())){
                    wxEmpEntry.setApprovalOpinion("不同意");
                }
                wxEmpEntry.setApprovalState(WxConstants.流程审批状态_驳回.getCode());
            }else {
                if(StringUtils.isEmpty(wxEmpEntry.getApprovalOpinion()) &&!WxConstants.分厂招聘流程_信息填报申请节点.getCode().equals(currentNode)&&!WxConstants.机关招聘流程_信息填报申请节点.getCode().equals(currentNode)){
                    wxEmpEntry.setApprovalOpinion("同意");
                }
                variableMap.put(FlowConstants.FLOW_ASSIGN_PERSON_KEY, wxEmpEntry.getApprover());
                wxEmpEntry.setApprovalState(WxConstants.流程审批状态_审批中.getCode());
            }

            flowParam.setVariableMap(variableMap);

            //更新审批人列表
            if(!WxConstants.分厂招聘流程_信息填报申请节点.getCode().equals(currentNode)&&!WxConstants.机关招聘流程_信息填报申请节点.getCode().equals(currentNode)){
                wxEmpEntry.setApproversList((wxEmpEntry.getApproversList()==null?"":wxEmpEntry.getApproversList())+("["+emp.getString("empNo")+"]"));
            }
        }
        if (!StringUtils.isEmpty(wxEmpEntry.getApprovalOpinion())) {
            flowParam.setOpinion(wxEmpEntry.getApprovalOpinion());
        }
        iWxEmpEntryService.updateById(wxEmpEntry);
        workflowService.commitTask(flowParam);
        return Result.ok();
    }
    /**
     * 审批结束后，更改审批状态
     * @param businessContext
     */
    @Transactional(rollbackFor=Exception.class)
    public void flowEndListener(BusinessContext businessContext) throws NoSuchAlgorithmException {
        WxEmpEntry wxEmpEntry = businessContext.get(WxEmpEntry.class);
        if(wxEmpEntry!=null && WxConstants.是.getCode().equals(wxEmpEntry.getIsPass())) {
            wxEmpEntry.setApprovalState(WxConstants.流程审批状态_审批通过.getCode());
            iWxEmpEntryService.updateById(wxEmpEntry);
        }
        // 审批全部通过，添加人员信息
        WxEmp emp =new WxEmp();
        BeanUtils.copyProperties(wxEmpEntry,emp);
        emp.setAccountNo(wxEmpEntry.getEmpNo());
        emp.setIsUse(WxConstants.是.getCode());
        emp.setEmpState(WxConstants.人员状态_在职.getCode());
        SysEmp sysEmp = new SysEmp();
        sysEmp.setEmpName(emp.getEmpName());
        sysEmp.setEmpNo(emp.getEmpNo());
        sysEmp.setAccountNo(emp.getAccountNo());
        sysEmp.setOrgNo(emp.getOrgNo());
        sysEmp.setCreateTime(LocalDateTime.now());
        sysEmp.setEmpPhone(emp.getEmpPhone());
        sysEmp.setIsUse(RightConstants.是.getCode());
        sysEmp.setProfilePicture(emp.getProfilePicture());
        rightExtService.addSysEmp(sysEmp);
        iWxEmpService.save(emp);

    }
    public void flowCommitListener(BusinessContext businessContext) {

    }

    @RequestMapping(value="/queryByInstanceId")
    public Result<?> queryByInstanceId(@RequestParam String instanceId) {
        if (StringUtils.isEmpty(instanceId)) {
            return Result.error("instanceId不能为空!");
        }
        QueryWrapper<WxEmpEntry> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WxEmpEntry::getInstanceId, instanceId);
        WxEmpEntry wxEmpEntry = iWxEmpEntryService.getOne(queryWrapper, false);
        List<ActHiComment> commentList = workflowService.getApprovedOpinionNew(instanceId);
        wxEmpEntry.setApprovalOpinions(commentList);
        return Result.ok(wxEmpEntry);
    }
    /**
     * 流程撤销
     * @param instanceId
     * @return
     */
    @GetMapping(value = "/cancel")
    @Transactional(rollbackFor=Exception.class)
    public Result<?> cancel(@RequestParam(name="instanceId",required=true) String instanceId) {
        LambdaQueryWrapper<WxEmpEntry> query = new LambdaQueryWrapper<>();
        query.eq(WxEmpEntry::getInstanceId, instanceId);
        WxEmpEntry wxEmpEntry = iWxEmpEntryService.getOne(query);
        if(wxEmpEntry==null) {
            return Result.error("员工离职信息不存在，不能进行撤销");
        }
        JSONObject emp = currentLoginEmp.getCurrentLoginInfo();
        if(!wxEmpEntry.getApplicationEmpNo().equals(emp.getString("empNo"))) {
            return Result.error("不是提交人，不能进行撤销操作");
        }

        //流程撤销
        workflowService.stopFlow(instanceId, "撤销");
        //删除入职申请信息
        iWxEmpEntryService.removeById(wxEmpEntry.getKeyId());
        return Result.ok();
    }
}

